<template>
  <div ref="isolatedContainer" class="isolated-wrapper">
    <!-- 内容将通过 Shadow DOM 渲染 -->
  </div>
</template>

<script setup lang="ts">
  import { nextTick, onBeforeUnmount, onMounted, watch, ref } from 'vue';

  interface Props {
    content: string;
    styles?: string;
    resetStyles?: boolean;
    mode?: 'closed' | 'open';
  }

  interface Emits {
    (e: 'mounted', shadowRoot: ShadowRoot): void;
    (e: 'updated'): void;
    (e: 'error', error: Error): void;
  }

  const props = withDefaults(defineProps<Props>(), {
    styles: '',
    resetStyles: true,
    mode: 'open',
  });

  const emit = defineEmits<Emits>();

  const isolatedContainer = ref<HTMLElement>();
  let shadowRoot: null | ShadowRoot = null;

  // 默认重置样式
  const getResetStyles = () => `
  :host {
    display: block;
    contain: layout style paint;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
    font-size: 14px;
    line-height: 1.5;
    color: #333333;
    background: transparent;
  }

  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }

  /* 重新定义常用标签的基础样式 */
  h1, h2, h3, h4, h5, h6 {
    font-weight: bold;
    line-height: 1.2;
    margin: 16px 0 8px 0;
  }

  h1 { font-size: 2em; }
  h2 { font-size: 1.5em; }
  h3 { font-size: 1.25em; }
  h4 { font-size: 1.1em; }
  h5 { font-size: 1em; }
  h6 { font-size: 0.9em; }

  p {
    margin: 8px 0;
    line-height: 1.6;
  }

  a {
    color: #1890ff;
    text-decoration: none;
    cursor: pointer;
  }

  a:hover {
    text-decoration: underline;
  }

  ul, ol {
    margin: 8px 0;
    padding-left: 24px;
  }

  li {
    margin: 4px 0;
  }

  img {
    max-width: 100%;
    height: auto;
  }

  table {
    border-collapse: collapse;
    width: 100%;
    margin: 8px 0;
  }

  th, td {
    border: 1px solid #ddd;
    padding: 8px;
    text-align: left;
  }

  th {
    background-color: #f5f5f5;
    font-weight: bold;
  }

  code {
    background: #f5f5f5;
    padding: 2px 4px;
    border-radius: 3px;
    font-family: 'Monaco', 'Consolas', monospace;
    font-size: 0.9em;
  }

  pre {
    background: #f5f5f5;
    padding: 12px;
    border-radius: 4px;
    overflow-x: auto;
    margin: 8px 0;
  }

  pre code {
    background: transparent;
    padding: 0;
  }

  blockquote {
    border-left: 4px solid #ddd;
    margin: 8px 0;
    padding-left: 16px;
    color: #666;
  }

  hr {
    border: none;
    border-top: 1px solid #ddd;
    margin: 16px 0;
  }
`;

  // 更新内容
  const updateContent = async () => {
    if (!shadowRoot) return;

    try {
      const baseStyles = props.resetStyles ? getResetStyles() : '';

      shadowRoot.innerHTML = `
      <style>
        ${baseStyles}
        ${props.styles}
      </style>
      <div class="isolated-content">
        ${props.content}
      </div>
    `;

      await nextTick();
      emit('updated');
    } catch (error) {
      emit('error', error as Error);
    }
  };

  // 初始化 Shadow DOM
  const initShadowDOM = async () => {
    try {
      if (!isolatedContainer.value) return;

      shadowRoot = isolatedContainer.value.attachShadow({ mode: props.mode });

      await updateContent();

      emit('mounted', shadowRoot);
    } catch (error) {
      emit('error', error as Error);
    }
  };

  // 获取 Shadow Root 实例
  const getShadowRoot = () => shadowRoot;

  // 在 Shadow DOM 中执行查询
  const querySelector = (selector: string) => {
    return shadowRoot?.querySelector(selector) || null;
  };

  const querySelectorAll = (selector: string) => {
    return shadowRoot?.querySelectorAll(selector) || null;
  };

  // 暴露方法给父组件
  defineExpose({
    getShadowRoot,
    querySelector,
    querySelectorAll,
    updateContent,
  });

  onMounted(() => {
    initShadowDOM();
  });

  watch([() => props.content, () => props.styles, () => props.resetStyles], updateContent, {
    deep: true,
  });

  onBeforeUnmount(() => {
    shadowRoot = null;
  });
</script>

<style scoped>
  .isolated-wrapper {
    display: block;
    width: 100%;
  }
</style>
